package com.naza.rpc.circuitBreaker;

/**
 * 
 * 熔断器状态 - 关闭
 *
 * @author yl
 */
final class ClosedState extends CircuitBreakerState {

    private final CircuitBreakerMetrics circuitBreakerMetrics;

    //当前的失败率
    private final float failureRateThreshold;

    ClosedState(CircuitBreakerImpl circuitBreaker) {
        super(circuitBreaker);
        this.circuitBreakerMetrics = new CircuitBreakerMetrics(
                circuitBreaker.getCircuitBreakerConfig().getRingBufferSizeInClosedState());
        this.failureRateThreshold = circuitBreaker.getCircuitBreakerConfig()
                .getFailureRateThresholdInClosedState();
    }

    /**
     * Returns always true, because the CircuitBreaker is closed.
     *
     * @return always true, because the CircuitBreaker is closed.
     */
    @Override
    boolean isCallPermitted() {
        return true;
    }

    @Override
    void recordFailure() {
        checkFailureRate(circuitBreakerMetrics.recordFailure());
    }

    @Override
    void recordSuccess() {
        checkFailureRate(circuitBreakerMetrics.recordSuccess());
    }

    /**
     * 如果当前失败率高于阈值，转变状态为打开状态
     * Checks if the current failure rate is above the threshold. If the failure
     * rate is above the threshold, transitions the state machine to OPEN state.
     *
     * @param currentFailureRate
     *            the current failure rate
     */
    private void checkFailureRate(float currentFailureRate) {
        if (currentFailureRate >= failureRateThreshold) {
            // Transition the state machine to OPEN state, because the failure
            // rate is above the threshold 熔断器状态从关闭 -> 打开
            circuitBreaker.transition(CircuitBreaker.State.CLOSED, CircuitBreaker.State.OPEN);
        }
    }

    /**
     * Get the state of the CircuitBreaker
     */
    @Override
    CircuitBreaker.State getState() {
        return CircuitBreaker.State.CLOSED;
    }

}
